package com.wulinbus.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import com.fancy.common.StoreFileTypeEnum;
import com.fancy.common.results.Results;
import com.fancy.common.utils.Config;
import com.fancy.common.utils.StringUtil;
import com.fancy.common.utils.http.HttpUtil;
import com.fancy.common.utils.http.HttpUtil.HTTPMethod;
import com.google.common.base.Function;

public class FileStore {
	/**
	 * 日志记录器
	 */
	private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
	// 允许的文件大小
	
	private final static Long MAX_SMALL_SIZE = Config.getLong("upload.file.small.size");
	private final static Long MAX_BIG_SIZE = Config.getLong("upload.file.big.size");
	public static final long KB = 1024;
	public static final long MB = KB*1024;
	public static final long GB = MB*1024;
	// 允许的文件类型
	
	private final static String ALLOW_TYPE = Config.getString("upload.image.type");
	// 存储根目录
	
	private final static String UPLOAD_ROOT = Config.getString("upload.image.root");
	
	/**
	 * 保存文件到本地
	 * 
	 * @param file
	 * @param fileType
	 * @return
	 */
	public static Results<String> saveFile(String uploadflag,final MultipartFile file, final String fileType,final String uniqueTag) {
		
		Assert.notNull(file, "file not be null");
		Assert.notNull(fileType, "fileType not be null");
		final Results<String> result = new Results<String>();
		try {
			// 扩展名
			String suffix = StringUtil.getSuffixName(file.getOriginalFilename());
			Long size = file.getSize();
			if(fileType.equals(StoreFileTypeEnum.IMAGES.toString()))
			{
				if (checkType(StoreFileTypeEnum.IMAGES.toString(),suffix)) 
				{
					if (size <= MAX_SMALL_SIZE)
						return saveFile(file.getInputStream(), suffix, fileType,null);
					else
						result.setMessage("文件不能超过10M!");
				}
				else
				{
					result.setMessage("只能上传"+ALLOW_TYPE+"类型的文件");
				}
			}
			else if(fileType.equals(StoreFileTypeEnum.FILES.toString())){
				if(StringUtil.isEmpty(uploadflag))
				{
					if(size <= MAX_SMALL_SIZE)
						return saveFile(file.getInputStream(), suffix, fileType,null);
					else
						result.setMessage("文件不能超过10M!");
				}
				else
				{
					if (size <= MAX_BIG_SIZE)
						return saveFile(file.getInputStream(), suffix, fileType,null);
					else
						result.setMessage("文件不能超过100M!");
				}
			}
			else
			{
				result.setMessage("未识别文件类型!");	
			}
			result.setSuccess(false);		
			return result;
		} catch (IOException e) {
			
			logger.error("save multipart file error", e);
			result.setMessage("save multipart file error");
			result.setSuccess(false);
			return result;
		}
	}

	/**
	 * 保存文件到本地
	 * 
	 * @param is
	 * @param fileType
	 * @return
	 */
	public static Results<String> saveFile(final InputStream is, final String extension, final String fileType,final String uniqueTag) {
		Assert.notNull(is, "is not be null");
		Assert.notNull(fileType, "fileType not be null");

		// 取得文件保存目录，不存在则生成之
		final String savePath = (StringUtil.isEmpty(uniqueTag)?"":uniqueTag+"/")+(fileType.equals(StoreFileTypeEnum.TEMPLATE.toString())?"":getSavePath(fileType));
		final File pathFile = new File(UPLOAD_ROOT, savePath);
		if (pathFile.exists() == false) {
			pathFile.mkdirs();
		}
		
		final String filePath = savePath + getName() + extension;
		final Results<String> result = new Results<String>();
		result.setObject(filePath);

		// 保存文件
		try (FileOutputStream fos = new FileOutputStream(new File(UPLOAD_ROOT, filePath))) {
			FileCopyUtils.copy(is, fos);
			result.setSuccess(true);
		} catch (IOException e) {
			logger.error("save file to:[],[]", filePath, e);
			result.setMessage("save file error");
			result.setSuccess(false);
		}
		return result;
	}
	/**
	 * 保存图片文件到本地，大小限制10M，且只允许（gif,png,bmp,jpg,jpeg）格式文件
	 * 
	 * @param image
	 * @param fileType
	 * @return
	 */
	public static Results<String> saveImage(String uploadflag,final MultipartFile image, final String fileType) {
		Assert.notNull(image, "image not be null");
		Assert.notNull(fileType, "fileType not be null");
		return saveFile(uploadflag,image, fileType,null);
	}
	/**
	 * 判断文件类型是否合法
	 * 
	 * @param type
	 * @return
	 */
	private static Boolean checkType(final String checkType ,final String type) {
		if(checkType.equals(StoreFileTypeEnum.IMAGES.toString()))
		{
			if(StringUtil.isEmpty(ALLOW_TYPE))
				return true;
			if (ALLOW_TYPE.contains(type)) 
			{
				return true;
			} 
			else 
			{
				return false;
			}
		}
		return false;
	}
	
	private static String getFriendSizeTip(final long size){
		if(size<KB)
			return size+"B";
		if(size<MB)
			return size*1.0/KB+"KB";
		if(size<GB)
			return size*1.0/MB+"MB";
		return size*1.0/GB+"GB";
	}
	/**
	 * 获取文件路径
	 * 
	 * @param fileType
	 * @return
	 */
	private static String getSavePathByDate(final String fileType) {
		return fileType.toString() + "/" + PATH_FORMAT.format(new Date());
	}
	
	private static String getSavePath(final String fileType) {
		return fileType.toString() + "/";
	}
	/**
	 * 获取文件名称(采用GUID)
	 * 
	 * @return
	 */
	private static String getName() {
		return UUID.randomUUID().toString();
	}
	// 年月日来分的文件目录
	private static final DateFormat PATH_FORMAT = new SimpleDateFormat("yyyy/MM/dd/");
}
